Skip to content

Revert "Fix datamapper button not appearing"#1895

Merged
KCSAbeywickrama merged 1 commit intorelease/bi-1.8.xfrom
revert-1832-fix-helper-item-datamapper-button
Apr 3, 2026
Merged

Revert "Fix datamapper button not appearing"#1895
KCSAbeywickrama merged 1 commit intorelease/bi-1.8.xfrom
revert-1832-fix-helper-item-datamapper-button

Conversation

@KCSAbeywickrama
Copy link
Copy Markdown
Contributor

@KCSAbeywickrama KCSAbeywickrama commented Apr 3, 2026

Reverts #1832
wso2/product-integrator#254 is addressed with #1893

Summary by CodeRabbit

  • Refactor

    • Converted form type selection handling from asynchronous to synchronous operations
    • Simplified type change handler implementation across form components
    • Removed error handling mechanisms for type change operations
  • Style

    • Minor formatting adjustments to form component code

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

The changes convert asynchronous type-change handlers to synchronous across multiple form components. Error handling with try/catch blocks and promise-based flows are removed. The handleSelectedTypeChange callback signature is narrowed from void | Promise<void> to just void, eliminating async support.

Changes

Cohort / File(s) Summary
Handler Synchronization
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx, workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/DeclareVariableForm/index.tsx
Refactored handleSelectedTypeChange from async to synchronous. Removed try/catch error handling, eliminated awaits on updateRecordTypeFields() and fetchVisualizableFields(), and removed side effects from type selection logic including cache clearing and field fetching in early-return paths.
Form Props & Internal Handlers
workspaces/ballerina/ballerina-side-panel/src/components/Form/index.tsx
Narrowed FormProps.handleSelectedTypeChange return type from void | Promise<void> to void. Removed promise wrapping and error logging in handleNewTypeSelected. Introduced new internal handleOnTypeChange function that calls getVisualiableFields() and passes it down to FieldFactory instances.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A rabbit hops through async webs so tangled,
But now the promises are neatly mangled! ✨
With void returns, the handlers skip and play,
Synchronous simplicity saves the day! 🐰

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main action: reverting a previous commit that attempted to fix the datamapper button appearing issue.
Description check ✅ Passed The description is minimal but sufficient for a revert PR, providing issue references and links to the original commit and alternative fix, though it does not follow the full template structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert-1832-fix-helper-item-datamapper-button

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reverts the earlier “Fix datamapper button not appearing” change set, aligning BI form/type-selection behavior with the newer fix referenced in #1893 and simplifying type-change handling across the visualizer and side-panel form components.

Changes:

  • Simplifies handleSelectedTypeChange in FormGenerator (removes async logic/error handling and some visualizable-field fetch paths).
  • Updates the side-panel Form API to make handleSelectedTypeChange synchronous and adjusts callers accordingly.
  • Adds a handleOnTypeChange hook in the side-panel Form to refresh visualizable fields when the type field changes.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx Reverts async type-selection flow; removes some visualizable-field fetching paths and try/catch handling.
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/DeclareVariableForm/index.tsx Updates type-change forwarding to match the now-synchronous handleSelectedTypeChange.
workspaces/ballerina/ballerina-side-panel/src/components/Form/index.tsx Changes handleSelectedTypeChange type signature and wires handleOnTypeChange to refresh visualizable fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Promise.resolve(handleSelectedTypeChange?.(type)).catch((error) => {
console.error("Error in handleSelectedTypeChange", error);
});
handleSelectedTypeChange(type);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleSelectedTypeChange is optional on FormProps, but it’s being called unconditionally here. If a caller doesn’t provide it, this will throw at runtime when the user changes the type. Guard with optional chaining (or a default no-op) similar to the previous implementation, and keep error handling if the callback can fail.

Suggested change
handleSelectedTypeChange(type);
handleSelectedTypeChange?.(type);

Copilot uses AI. Check for mistakes.
console.error("Error handling selected type change", error);
const handleSelectedTypeChange = (type: CompletionItem | string) => {
if (typeof type === "string") {
handleSelectedTypeByName(type);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleSelectedTypeByName is async, but handleSelectedTypeChange now calls it without awaiting or handling rejections. This can lead to unhandled promise rejections (and out-of-order state updates) when type resolution fails or the RPC call throws. Consider making handleSelectedTypeChange async and awaiting the call, or explicitly catching/logging the promise.

Suggested change
handleSelectedTypeByName(type);
void handleSelectedTypeByName(type).catch((error) => {
console.error("Failed to handle selected type by name:", error);
});

Copilot uses AI. Check for mistakes.
Comment on lines 1463 to 1474
const handleSelectedTypeByName = async (typeName: string) => {
// Early return for invalid input
if (!typeName || typeName.length === 0) {
importsCodedataRef.current = null;
await fetchVisualizableFields(fileName, typeName);
setValueTypeConstraints('');
return;
}

const type = await searchImportedTypeByName(typeName);
if (!type) {
importsCodedataRef.current = null;
await fetchVisualizableFields(fileName, typeName);
setValueTypeConstraints('');
return;
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When typeName is empty/invalid or the type can’t be found, this function now returns without updating/clearing visualizableField (and without resetting importsCodedataRef). Since visualizableField is used to decide whether the Data Mapper button is enabled and to provide default values, it can become stale after a type is cleared/changed. Consider explicitly resetting visualizableField (and importsCodedataRef.current) on these early-return paths, or triggering a refresh that results in a cleared state.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@senithkay senithkay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx (1)

1402-1409: handleSelectedTypeChange converted to synchronous with reduced side effects.

Key changes in this revert:

  1. handleSelectedTypeByName(type) is called without await — this async function now runs fire-and-forget
  2. The CompletionItem branch no longer clears importsCodedataRef.current or fetches visualizable fields

The fire-and-forget pattern for handleSelectedTypeByName means any errors will be unobserved (no rejection handler). If the async operations in that path need error visibility, consider adding a .catch():

♻️ Optional: Add error logging for fire-and-forget async call
 const handleSelectedTypeChange = (type: CompletionItem | string) => {
     if (typeof type === "string") {
-        handleSelectedTypeByName(type);
+        handleSelectedTypeByName(type).catch((error) => {
+            console.error(">>> Error handling type change by name", error);
+        });
         return;
     }
     setSelectedType(type);
     updateRecordTypeFields(type);
 };

Based on learnings, the CompletionItem branch changes are safe in the current flow and will be revisited after the "unifying efforts of types API calls" work is complete.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx`
around lines 1402 - 1409, In handleSelectedTypeChange, the string branch calls
handleSelectedTypeByName(type) fire-and-forget which leaves any errors
unobserved and also removed previous side-effects; change that call to
handleSelectedTypeByName(type).catch(err => /* log error */) to surface
rejections, and restore the prior side-effects by clearing
importsCodedataRef.current (set to null/undefined) and invoking the routine that
fetches/updates visualizable fields (e.g., fetchVisualizableFields or
updateRecordTypeFields) as the original flow did so you still reset
importsCodedataRef and populate fields; reference: handleSelectedTypeChange,
handleSelectedTypeByName, importsCodedataRef.current,
fetchVisualizableFields/updateRecordTypeFields, setSelectedType.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/DeclareVariableForm/index.tsx`:
- Around line 35-37: The call to handleSelectedTypeChange inside
handleOnTypeChange can throw because handleSelectedTypeChange is optional in
FormProps; add a defensive null-check or optional chaining before invoking it
(e.g., if (handleSelectedTypeChange) handleSelectedTypeChange(type) or
handleSelectedTypeChange?.(type)) so handleOnTypeChange safely handles the case
when handleSelectedTypeChange is undefined; update the handleOnTypeChange
function to perform this guard using the existing parameter names.

---

Nitpick comments:
In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx`:
- Around line 1402-1409: In handleSelectedTypeChange, the string branch calls
handleSelectedTypeByName(type) fire-and-forget which leaves any errors
unobserved and also removed previous side-effects; change that call to
handleSelectedTypeByName(type).catch(err => /* log error */) to surface
rejections, and restore the prior side-effects by clearing
importsCodedataRef.current (set to null/undefined) and invoking the routine that
fetches/updates visualizable fields (e.g., fetchVisualizableFields or
updateRecordTypeFields) as the original flow did so you still reset
importsCodedataRef and populate fields; reference: handleSelectedTypeChange,
handleSelectedTypeByName, importsCodedataRef.current,
fetchVisualizableFields/updateRecordTypeFields, setSelectedType.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7fa3f392-eda9-4413-9432-3cf682e41b10

📥 Commits

Reviewing files that changed from the base of the PR and between 85894ba and 9cfa480.

📒 Files selected for processing (3)
  • workspaces/ballerina/ballerina-side-panel/src/components/Form/index.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/DeclareVariableForm/index.tsx
  • workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx

Comment on lines 35 to 37
const handleOnTypeChange = (type: string | CompletionItem) => {
Promise.resolve(handleSelectedTypeChange?.(type)).catch((error) => {
console.error("Error in handleSelectedTypeChange", error);
});
handleSelectedTypeChange(type);
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing null check after removing optional chaining.

The handleSelectedTypeChange prop is optional (per FormProps), but the revert removed the optional chaining safeguard (?.). If this prop is ever undefined, the call will throw a TypeError.

While FormGenerator always passes this prop when rendering VariableForm, the component interface still allows it to be omitted. Consider adding a guard:

🛡️ Proposed fix to restore defensive check
 const handleOnTypeChange = (type: string | CompletionItem) => {
-    handleSelectedTypeChange(type);
+    handleSelectedTypeChange?.(type);
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleOnTypeChange = (type: string | CompletionItem) => {
Promise.resolve(handleSelectedTypeChange?.(type)).catch((error) => {
console.error("Error in handleSelectedTypeChange", error);
});
handleSelectedTypeChange(type);
};
const handleOnTypeChange = (type: string | CompletionItem) => {
handleSelectedTypeChange?.(type);
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/DeclareVariableForm/index.tsx`
around lines 35 - 37, The call to handleSelectedTypeChange inside
handleOnTypeChange can throw because handleSelectedTypeChange is optional in
FormProps; add a defensive null-check or optional chaining before invoking it
(e.g., if (handleSelectedTypeChange) handleSelectedTypeChange(type) or
handleSelectedTypeChange?.(type)) so handleOnTypeChange safely handles the case
when handleSelectedTypeChange is undefined; update the handleOnTypeChange
function to perform this guard using the existing parameter names.

@KCSAbeywickrama KCSAbeywickrama merged commit f3a5fe5 into release/bi-1.8.x Apr 3, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants